import json
from typing import Any
from simpleutil import classes
import copy


def json_obj_configuration(
    weed_out_none_in_dict=True,
    weed_out_none_in_collection=False,
    only_retain_class_annotations=True,
):
    return {
        "weed_out_none_in_dict": weed_out_none_in_dict,
        "weed_out_none_in_collection": weed_out_none_in_collection,
        "only_retain_class_annotations": only_retain_class_annotations,
    }


def json_str_configuration(
    kv_spaces_num=-1,  # k:${ 空格 * kv_spaces_num}v。 -1 表示不做处理
    skipkeys=False,
    ensure_ascii=True,
    check_circular=True,
    allow_nan=True,
    cls=None,
    indent=None,
    separators=None,
    default=None,
    sort_keys=False,
):
    if not isinstance(kv_spaces_num, int) or kv_spaces_num < -1:
        kv_spaces_num = -1
    return {
        "common_config": {
            "kv_spaces_num": kv_spaces_num,
        },
        "dumps_config": {
            "skipkeys": skipkeys,
            "ensure_ascii": ensure_ascii,
            "check_circular": check_circular,
            "allow_nan": allow_nan,
            "cls": cls,
            "indent": indent,
            "separators": separators,
            "default": default,
            "sort_keys": sort_keys,
        },
    }


def convert_json_object(
    json_obj,
    weed_out_none_in_dict=True,
    weed_out_none_in_collection=False,
    only_retain_class_annotations=True,
) -> Any:
    type_ = type(json_obj)
    if not json_obj or classes.is_inbuilt_single_type(type_=type_):
        return json_obj
    elif classes.is_collection_type(type_=type_):
        return [
            convert_json_object(json_obj=item) for item in json_obj if (not weed_out_none_in_collection) or (item is not None)
        ]
    elif isinstance(json_obj, dict):
        return {
            k: convert_json_object(json_obj=v) for k, v in json_obj.items() if (not weed_out_none_in_dict) or (v is not None)
        }
    else:
        dict_: dict = copy.deepcopy(x=json_obj.__dict__)
        if only_retain_class_annotations:
            return {
                key: convert_json_object(json_obj=value)
                for key, value in vars(json_obj).items()
                if (key in classes.get_all_annotations(obj=json_obj)) and (value is not None)
            }
        else:
            return dict_
